// DeletePrinter.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "InstalledPrinters.h"


void MyEnumMonitors ()
{
	int num = 1024;
	LPBYTE pMonitors = new byte[num];
	LPDWORD pcbNeeded = new DWORD[num];
	LPDWORD pcReturned = new DWORD[num];

	int ret = EnumMonitors(NULL,1,pMonitors,num,pcbNeeded,pcReturned);
	int errorCode = GetLastError();
	std::cout << "ret = " << ret << std::endl;
	std::cout << "errorCode = " << errorCode << std::endl;
	delete pMonitors;
	pMonitors = NULL;
	delete pcbNeeded;
	pcbNeeded = NULL;
	delete pcReturned;
	pcReturned = NULL;
}

void MyGetPort()
{
	DWORD dwSize = 0;
	DWORD dwPorts = 0;
	LPBYTE pBuffer = NULL;
	int errCode = 0;

	if (!EnumPorts (NULL, 2, pBuffer, 0, &dwSize, &dwPorts))
	{
		errCode = GetLastError();
	}

	pBuffer = new BYTE [dwSize];
	if (pBuffer == NULL)
	{
		return;
	}

	if (!EnumPorts (NULL, 2, pBuffer, dwSize, &dwSize, &dwPorts))
	{
		errCode = GetLastError();
	}
	if (dwPorts == 0)
	{
		return;
	}

	PORT_INFO_2* pInfo = (PORT_INFO_2*)pBuffer;

	for (DWORD i = 0; i < dwPorts; i++, pInfo++)
	{
		std::wstring str = (std::wstring)(pInfo->pPortName);
		std::wcout << "[GetPort] PortName= " << str << std::endl;

		str = (std::wstring)(pInfo->pMonitorName);
		std::wcout << "[GetPort] MonitorName= " << str << std::endl;

		str = (std::wstring)(pInfo->pDescription);
		std::wcout << "[GetPort] MonitorName= " << str << std::endl;

		std::wcout << "[GetPort] MonitorName= " << pInfo->fPortType << std::endl;
	}

	delete [] pBuffer;
}

void MyGetPrinter ()
{
	DWORD dwSize = 0;
	DWORD dwPrinters = 0;

	if (!EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &dwSize, &dwPrinters))
	{
		if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			return;
		}
	}

	LPBYTE pBuffer = new BYTE [dwSize];
	if (pBuffer == NULL)
	{
		return;
	}

	if (!EnumPrinters (PRINTER_ENUM_LOCAL, NULL, 2, (PBYTE) pBuffer, dwSize, &dwSize, &dwPrinters))
	{
		if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			return;
		}
	}
	if (dwPrinters == 0)
	{
		return;
	}

	PRINTER_INFO_2* pInfo = (PRINTER_INFO_2*)pBuffer;

	for (DWORD i = 0; i < dwPrinters; i++, pInfo++)
	{
		std::wstring str = (std::wstring)(pInfo->pPrinterName);
		std::wcout << "[GetPrinter] PrinterName= " << str << std::endl;

		str = (std::wstring)(pInfo->pDriverName);
		std::wcout << "[GetPrinter] DriverrName= " << str << std::endl;
	}

	delete [] pBuffer;
}

void MyOpenPrinter()
{
	int errCode = 0;
	LPTSTR pPrinterName = _T("KODAK HERO 7.1 AiO XPS");
	HANDLE handler = 0;

	PRINTER_DEFAULTS printerDefaults;
	printerDefaults.pDatatype = 0;
	printerDefaults.pDevMode = 0;
	printerDefaults.DesiredAccess = PRINTER_ALL_ACCESS; 

	if (!OpenPrinter(pPrinterName,&handler,&printerDefaults))
	{
		errCode = GetLastError();
		if (errCode != ERROR_INSUFFICIENT_BUFFER)
		{
			//return;
		}
	}

	if (!DeleteFormA(handler,"8x10 in. (borderless)"))
	{
		errCode = GetLastError();
		if (errCode != ERROR_INSUFFICIENT_BUFFER)
		{
			//return;
		}
	}

	if (!DeletePrinter(handler))
	{
		errCode = GetLastError();
		if (errCode != ERROR_INSUFFICIENT_BUFFER)
		{
			//return;
		}
	}

/*
	if (!DeletePrinterConnection(handler))
	{
		errCode = GetLastError();
		if (errCode != ERROR_INSUFFICIENT_BUFFER)
		{
			//return;
		}
	}*/

	if (!ClosePrinter(handler))
	{
		errCode = GetLastError();
		if (errCode != ERROR_INSUFFICIENT_BUFFER)
		{
			//return;
		}
	}


	if (!ClosePrinter(handler))
	{
		errCode = GetLastError();
		if (errCode != ERROR_INSUFFICIENT_BUFFER)
		{
			//return;
		}
	}
}

void MyGetDrivers()
{
	DWORD dwSize = 0;
	DWORD dwDrivers = 0;

	if (!EnumPrinterDrivers (NULL, NULL, 6, NULL, 0, &dwSize, &dwDrivers))
	{
		if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			return;
		}
	}

	LPBYTE pBuffer = new BYTE [dwSize];
	if (pBuffer == NULL)
	{
		return;
	}

	if (!EnumPrinterDrivers (NULL, NULL, 6, (PBYTE) pBuffer, dwSize, &dwSize, &dwDrivers))
	{
		if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			return;
		}
	}
	if (dwDrivers == 0)
	{
		return;
	}

	DRIVER_INFO_6* pInfo = (DRIVER_INFO_6*)pBuffer;

	for (DWORD i = 0; i < dwDrivers; i++, pInfo++)
	{
		std::wstring str = (std::wstring)(pInfo->pName);
		std::wcout << "[GetDriver] Name= " << str << std::endl;
	}

	delete [] pBuffer;
}

void MyDeletePrinterDriver()
{
	int errCode = 0;
	if (!DeletePrinterDriverA(NULL, NULL, "KODAK OFFICE HERO 2.2 AiO XPS"))
	{
		errCode = GetLastError();
	}
}

int MyGetVersion(){
	
	DWORD dwVersion = 0; 
	DWORD dwMajorVersion = 0;
	DWORD dwMinorVersion = 0; 
	DWORD dwBuild = 0;

	dwVersion = GetVersion();

	// Get the Windows version.

	dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
	dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));

	// Get the build number.

	if (dwVersion < 0x80000000)              
		dwBuild = (DWORD)(HIWORD(dwVersion));

	printf("Windows Version is %d.%d (%d)\n", 
		dwMajorVersion,
		dwMinorVersion,
		dwBuild);
	return dwMajorVersion;
}

void MyDeletePrinterDriverPackage()
{
	int version = MyGetVersion();
	int errCode = 0;
	int result = 0;
	if (version>=6)
	{
		//result = DeletePrinterDriverPackageA(NULL,"\\oem77.inf",NULL);
		//result = DeletePrinterDriverPackageA(NULL,"C:\\Windows\\System32\\DriverStore\\FileRepository\\ekaio2xps.inf_amd64_neutral_423ec918b0094d2d\\EKAiO2XPS.inf",NULL);

		HINSTANCE hRet = ShellExecuteA(NULL,"pnputil","C:\\Windows\\winsxs\\amd64_microsoft-windows-pnputil_31bf3856ad364e35_6.1.7600.16385_none_5958b438d6388d15\\","-f -d OEM77.INF",NULL,SW_HIDE);

		if (!result)
		{
			errCode = GetLastError();
		}
	}
}

void MyGetMonitor()
{
	DWORD dwSize = 0;
	DWORD dwMonitors = 0;
	BYTE bMonitors = 0;
	LPBYTE pBuffer = NULL;
	int errCode = 0;

	if (!EnumMonitors (NULL, 2, pBuffer, 0, &dwSize, &dwMonitors))
	{
		errCode = GetLastError();
	}

	pBuffer = new BYTE [dwSize];
	if (pBuffer == NULL)
	{
		return;
	}

	if (!EnumMonitors (NULL, 2, pBuffer, dwSize, &dwSize, &dwMonitors))
	{
		if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
		{
			return;
		}
	}
	if (dwMonitors == 0)
	{
		return;
	}

	MONITOR_INFO_2* pInfo = (MONITOR_INFO_2*)pBuffer;

	for (DWORD i = 0; i < dwMonitors; i++, pInfo++)
	{
		std::wstring str = (std::wstring)(pInfo->pName);
		std::wcout << "[GetMonitor] Monitor Name= " << str << std::endl;
	}

	delete [] pBuffer;
}


int _tmain(int argc, _TCHAR* argv[])
{
	MyGetPrinter();
	MyGetDrivers();
	MyDeletePrinterDriverPackage();
	MyGetMonitor();
	MyGetPort();

	return 0;
}
